package com.haiyou.dc.netty.chat;

import com.alibaba.fastjson.JSON;
import com.haiyou.common.util.SpringUtil;
import com.haiyou.dc.netty.constant.ImChatConstant;
import com.haiyou.dc.netty.entity.ImChat;
import com.haiyou.dc.netty.entity.ImUser;
import com.haiyou.dc.netty.service.ImChatService;
import com.haiyou.dc.netty.service.ImUserService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 聊天拦截器
 */
@Slf4j
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        String text = msg.text();
        log.info("====>客户端传来的消息={}", text);

        Message message = JSON.parseObject(text, Message.class);
        log.info("====>message={}", message);
        if (ImChatConstant.Type.CONNECT.getType().equals(message.getType())) {
            ClientsMap.put(message.getSender(), ctx.channel());
        } else if (ImChatConstant.Type.CHAT.getType().equals(message.getType())) {

            //保存内容到数据库
            ImChatService imChatService = (ImChatService) SpringUtil.getBean("imChatServiceImpl");
            ImChat imChat = imChatService.listenerMessage(message);
            imChat.setBody(null);

            //发送消息
            sendSingleMessage(imChatService, message, imChat);
            String sender = message.getSender();
            message.setSender(message.getReceiver());
            message.setReceiver(sender);
            sendSingleMessage(imChatService, message, imChat);

        }

        log.info("====>客户端={}", ClientsMap.print());


    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("--->{}", cause);
        log.error("====>发生异常之后关闭连接（关闭channel），随后从ChannelGroup中移除");
        ctx.channel().close();
        clients.remove(ctx.channel());
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        clients.add(ctx.channel());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        log.info("====>客户端被移除，channelId={}", ctx.channel().id().asLongText());
        clients.remove(ctx.channel());
    }

    /**
     * 推送联系人消息/单聊消息
     */
    private void sendSingleMessage(ImChatService imChatService, Message message, ImChat imChat) {
        Channel channel = ClientsMap.get(message.getSender());
        if (channel == null) {
            //TODO 用户离线，推送消息（JPush、个推，小米推送等）
            log.info("------>用户离线1，推送消息（JPush、个推，小米推送等");
            return;
        }

        channel = clients.find(channel.id());
        if (channel == null) {
            //TODO 用户离线，推送消息（JPush、个推，小米推送等）
            log.info("------>用户离线2，推送消息（JPush、个推，小米推送等");
            return;
        }

        //最近联系人
        Map<String, Object> objectMap = imChatService.selectMessage(message.getSender());
        objectMap.put("actionType", ImChatConstant.ActionType.CHAT.getId());
        log.info("------->最近联系人推送消息={}", objectMap);
        channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(objectMap)));

        //单聊
        ImUserService imUserService = (ImUserService) SpringUtil.getBean("imUserServiceImpl");
        ImUser senderUser = imUserService.selectByPrimaryKey(message.getSender());
        ImUser receiverUser = imUserService.selectByPrimaryKey(message.getReceiver());
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("senderUser", senderUser);
        hashMap.put("receiverUser", receiverUser);
        hashMap.put("imChat", imChat);
        hashMap.put("actionType", ImChatConstant.ActionType.SIGNLE.getId());

        log.info("------->单聊推送消息={}", hashMap);
        channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(hashMap)));

    }
}
